package controllers

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"micro-bbs/datamodels"
	"micro-bbs/initialize"
	"micro-bbs/libs"
	"micro-bbs/services"
	"github.com/gin-gonic/gin"
	"net/http"
	"net/url"
	"strconv"
	"strings"
	"time"
)

type SsoController struct {
	BaseController
	SsoService services.UserInterfaceService
}

func NewSsoController() *SsoController {
	obj := &SsoController{
		SsoService: services.NewUserService(),
	}
	return obj
}

//根据code获取access_token信息
func (this *SsoController) Token(c *gin.Context){
	fmt.Println("22222222222222")
	//独立登录页面
	code :=c.Query("code")
	if code == "" {
		log.Println("code获取失败！")
		this.returnResult(4000, nil, "")
	}
	//获取sso统一登录令牌
	val := url.Values{}
	val.Add("grant_type", "authorization_code")
	val.Add("code", code) // Set Add 都可以
	val.Add("scope", "all") // Set Add 都可以
	val.Add("redirect_uri", "http://localhost:8082")

	body := strings.NewReader(val.Encode())
	req, err := http.NewRequest(http.MethodPost, "http://ssoserver.com:9096/token", body)
	//req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	req.Header.Set("Content-Type","application/x-www-form-urlencoded")
	//req.BasicAuth()
	req.SetBasicAuth("test_client_3", "test_secret_3")
	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		fmt.Println(err)
		return
	}
	defer resp.Body.Close()
	bs, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println("resp str:",string(bs))
	m := make(map[string]interface{})
	err = json.Unmarshal(bs, &m)
	if err != nil {
		fmt.Println("Umarshal failed:", err)
		return
	}
	fmt.Println("token_map:", m)
	//设置共享session
	sta :=initialize.RedisClient.Set("sso_client_login", string(bs),7000*time.Second)
	fmt.Println("sta:",sta)
	c.JSON(http.StatusOK, libs.ReturnJson(200,"", m))
}

//获取用户详情页
func (this *SsoController) Detail(c *gin.Context){
	idStr := c.Param("id")
	id, _ := strconv.Atoi(idStr)
	initialize.IrisLog.Infof("[用户控制器-http请求数据]-[%d]", id)

	result, err := this.SsoService.GetUserInfo(int64(id))
	initialize.IrisLog.Infof("[用户控制器-userInfo返回数据]-[%s]", libs.StructToJson(result))
	if err != nil {
		c.HTML(http.StatusNotFound, "error/404.html", gin.H{"title": "404"})
		return
	}

	//获取发布的帖子
	var query datamodels.PostByQuery
	uid := int64(id)
	query.UserId = &uid
	query.Limit = 15
	postList, _ := this.SsoService.GetPostByQuery(query)
	initialize.IrisLog.Infof("[用户控制器-postList返回数据]-[%s]", postList)

	//获取发布的评论
	//var query datamodels.ParamsPostCommentList
	//query.PostId = id
	//commentList, _ := this.PostService.GetPostCommentList(query)
	//initialize.IrisLog.Infof("[帖子控制器-commentList返回数据]-[%s]", libs.StructToJson(commentList))

	c.HTML(http.StatusOK, "user/detail.html", gin.H{
		"title": result.(datamodels.BbsUser).Nickname,
		"address": "bbs.100txy.com",
		"id": id,
		"data": result,
		"postData": postList,
	})
}

//获取登录用户信息
func (this *SsoController) LoginInfo(c *gin.Context){
	//用户信息
	var userinfo = make(map[string]interface{},0)
	//获取恭喜session
	sessionStr,err := initialize.RedisClient.Get("test_client_1").Result()
	if err != nil || len(sessionStr) == 0{
		//panic(err)
		c.JSON(http.StatusOK, libs.ReturnJson(200,"", gin.H{
			"userinfo": userinfo,
		}))
	}
	//if len(respBytes) == 0{
	//	return nil
	//}
	tokenMap := make(map[string]interface{})
	err = json.Unmarshal([]byte(sessionStr), &tokenMap)
	if err != nil {
		fmt.Println("Umarshal failed:", err)
		fmt.Println("sessionStr:",sessionStr)
		return
	}

	fmt.Println("tokenMap:", tokenMap)
	//效验token
	res := this.checkToken(c,tokenMap["access_token"].(string))
	if res.(map[string]interface{})["user_id"] != "" {
		//组装用户信息
		userinfo["id"] = 1
		userinfo["nickname"] = "雷小天"
		userinfo["is_admin"] = 1
		userinfo["vip"] = 5
		userinfo["head_img"] = "http://thirdqq.qlogo.cn/g?b=oidb&k=7iaib304zfK77M2ibtukgic1kQ&s=100&t=1617010816"
	}

	c.JSON(http.StatusOK, libs.ReturnJson(200,"", gin.H{
		"tokenMap": tokenMap,
		"res": res,
		"userinfo": userinfo,
	}))
}

//效验sso分发的access_token有效性
func (this *SsoController)checkToken(c *gin.Context, oauth_token string) interface{} {
	req, err := http.NewRequest(http.MethodGet, "http://ssoserver.com:9096/test", nil)
	req.Header.Set("Content-Type","application/x-www-form-urlencoded")
	req.Header.Set("Authorization","Bearer "+oauth_token)
	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		fmt.Println(err)
		return ""
	}
	defer resp.Body.Close()
	bs, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println(err)
		return ""
	}
	fmt.Println("resp str:",string(bs))//invalid access token
	m := make(map[string]interface{})
	err = json.Unmarshal(bs, &m)
	if err != nil {
		return ""
	}
	fmt.Println("map:", m)
	return m
}
